import { setToken, getToken, removeToken } from '@/utils/auth'
import { loginAPI, getUserProfileAPI, getUserPhotoAPI } from '@/api'
// 面试: 为何本地存token, 不直接使用本地token(在请求拦截器里)
// 为何要多此一举, 还要在vuex同步一份呢?
// 本地大家也可以去本地拿, 也可以像vuex一样共享
// 答案: vuex是存在内存里的, 取值更快, 浏览器本地存储是存在磁盘里(持久化), 操作磁盘比较慢
// 面试官表现出对答案不满意, 你可以适当的询问对方的高见

const getDefaultState = () => {
  return {
    token: getToken(), // 用户token
    userInfo: JSON.parse(localStorage.getItem('userInfo')) || {} // 用户信息(用户昵称username, 用户头像, ...等等)
  }
}
// 建议: 属性值将来是什么类型, 初始值就给什么类型

const state = getDefaultState()

const mutations = {
  // 重置当前模块state对象
  RESET_STATE: (state) => {
    // Object.assign() 是吧参数2往后的所有对象里key+value, 复制到第一个参数的对象身上
    // getDefaultState()调用后,拿到上面默认初始的state对象, 给现有state对象重新覆盖值
    Object.assign(state, getDefaultState())
  },
  // 设置token
  // 技巧: 按住shift键, 再按字母都大写的
  SET_TOKEN(state, newToken) {
    state.token = newToken
    setToken(newToken)
  },
  // 删除token
  REMOVE_TOKEN(state) {
    state.token = ''
    removeToken()
  },
  // 设置userInfo
  SET_USERINFO(state, value) {
    state.userInfo = value
    localStorage.setItem('userInfo', JSON.stringify(value))
  },
  // 删除userInfo
  REMOVE_USERINFO(state) {
    state.userInfo = {}
    localStorage.removeItem('userInfo')
  }
}

const actions = {
  // 登录逻辑-封装
  async loginActions({ commit }, value) {
    const [err, res] = await loginAPI(value)
    // 我们只需要token, 保存到上面的vuex中
    if (!err) commit('SET_TOKEN', res.data)
    // 逻辑页面还在接收数组, 外面写成功/失败的逻辑, 所以这里要把数组返回出去
    // return到actions调用的地方(login/index.vue)
    return [err, res]

    // try {
    //   const res = await loginAPI(value)
    //   // 我们只需要token, 保存到上面的vuex中
    //   // 响应拦截器里面我response.data了, 所以这里拿到的是后台返回数据对象
    //   // res.data就是token, 如果没用里面.data一次, 那这里就是res.data.data
    //   commit('SET_TOKEN', res.data)
    //   // 逻辑页面还在接收数组, 外面写成功/失败的逻辑, 所以这里要把数组返回出去
    //   // return到actions调用的地方(login/index.vue)
    //   return res // 逻辑页面登录页那边接收的也不是数组
    // } catch (err) {
    //   // 外面也有try+catch
    //   // actions本身返回的也是一个Promise对象
    //   // 逻辑页面也得用await 取值
    //   return Promise.reject(err)
    //   // 因为这里没有resolve和reject 所以要用Promise.reject()
    // }
  },
  // 获取用户信息
  // 默认第一个形参store 以前store.commit()
  // {commit} = store对象的解构赋值, 把store对象里的commit方法直接赋予给了左侧的{}里的commit变量
  async getUserInfoActions({ commit }, value) {
    const res = await getUserProfileAPI()
    const user = await getUserPhotoAPI(res.data.userId)
    // res.data和user.data的2个对象里key+value合并成一个对象
    // 赋予给userInfo保存 (我们要的数据来自于2个接口对象中)
    commit('SET_USERINFO', { ...res.data, ...user.data }) // 保存用户基本信息
  },
  // 退出登录
  logOutActions({ commit }) {
    // 删除vuex和本地token
    // 先清除本地的token, 然后在重置state(因为上面重置state还会去本地取一次)
    // 跳转不了, 多想想路由守卫+token的事情
    commit('REMOVE_TOKEN')
    commit('RESET_STATE')
  }
}
// commit -> 触发 mutations方法 (固定)
// dispatch -> 触发 actions方法 (固定)

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

